#include "uart_protocol.h"
#include "HardWare/OLED.h"
extern UART_HandleTypeDef huart1;
#define BUFFER_SIZE 11
uint8_t rx_buffer[BUFFER_SIZE]; // 接收缓冲区
uint16_t rx_count;              // 接收数据计数
ProtocolMutliTurnDecode rxData_PMTD;

PMTF uart_sendDataPackage()
{
    uint32_t absCnt = 16777000;
    uint32_t multiTurnCnt = 8333333;
    uint8_t crc = 0x35;
    PMTF pData;
    pData.Frame_0.FrameHeaderFlag = 1;
    pData.Frame_0.ReserveDataFlag = 0;
    pData.Frame_0.ReserveBit = 2;
    pData.Frame_1.ReserveBit1 = 3;
    pData.Frame_5.ReserveBit2 = 4;
    pData.Frame_9.ReserveBit3 = 5;
    pData.Frame_10.Frame_CRC6 = crc;
    pData.Frame_10.Valid = 1;

    pData.Frame_1.Flag_0 = 0;
    pData.Frame_2.Flag_0 = 0;
    pData.Frame_3.Flag_0 = 0;
    pData.Frame_4.Flag_0 = 0;
    pData.Frame_5.Flag_0 = 0;
    pData.Frame_6.Flag_0 = 0;
    pData.Frame_7.Flag_0 = 0;
    pData.Frame_8.Flag_0 = 0;
    pData.Frame_9.Flag_0 = 0;
    pData.Frame_10.Flag_0 = 0;

    // 多圈
    pData.Frame_1.MultiTurn = (multiTurnCnt & 0xE00000) >> 21;
    pData.Frame_2.MultiTurn = (multiTurnCnt & 0x1FC000) >> 14;
    pData.Frame_3.MultiTurn = (multiTurnCnt & 0x3F80) >> 7;
    pData.Frame_4.MultiTurn = (multiTurnCnt & 0x7F);
    // 绝对位置
    pData.Frame_5.ABS_Pos = (absCnt & 0xE00000) >> 21;
    pData.Frame_6.ABS_Pos = (absCnt & 0x1FC000) >> 14;
    pData.Frame_7.ABS_Pos = (absCnt & 0x3F80) >> 7;
    pData.Frame_8.ABS_Pos = (absCnt & 0x7F);
    return pData;

}
void DMA_UART_Init()
{
    // 启动DMA接收
    HAL_UART_Receive_DMA(&huart1, rx_buffer, BUFFER_SIZE);
}

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    if(huart->Instance == USART1)
    {
        // 1.解码数据
        if(RES_OK != DecodeToMultiTurn(rx_buffer,BUFFER_SIZE,&rxData_PMTD)){
            if(!rxData_PMTD.CrcError){
                rx_count++;
            }
        }

        // 2.数据写入 BKP

//        rxData_PMTD = rx_DecodeToMultiTurn(rx_buffer,BUFFER_SIZE);
        OLED_ShowNum(2,3,rxData_PMTD.MutliTurnCnt,8);
        OLED_ShowNum(3,3,rxData_PMTD.AbsPoseCnt,8);
        OLED_ShowNum(4,4,rx_count,4);
    }
}
/**
 * @brief 协议解码，根据给定的size 进行解码，返回数据包中解码成功的数据
 * */
ProtocolMutliTurnDecode Rx_DecodeToMultiTurn(const uint8_t* rxByteArray,uint16_t size)
{
    uint32_t index = 0;
    ProtocolMutliTurnDecode rxData={0};
    uint8_t pData[size];

    // copy data
    for (int i = 0; i <size ; ++i) {
        pData[i] = rxByteArray[i];
    }

    // decode byteInFrames=11
    while (index < size) {
        if (!(*(pData + index) & 0x80)) {
            ++index;
            continue;
        }
        DecodeToMultiTurn((pData + index),size-index,&rxData);
        ++index;
    }
    return rxData;
}

int8_t DecodeToMultiTurn(uint8_t* pData,uint16_t size,ProtocolMutliTurnDecode* dstValue)
{
    uint8_t byteInFrames=11;
    if(size<byteInFrames)
        return ERR_PROTOCOL_SIZE ;
    if(!(*pData & 0x80)){
        return ERR_PROTOCOL_DATA;
    }

    if(!crc6Check((pData),byteInFrames)){
        dstValue->CrcError = 1;
    }

    if(!(pData[size]&0x01)){
        dstValue->CrcError = 0;
        dstValue->ReserveDataFlag = (pData[0]&0x70)>>4;
        dstValue->ReserveBit = pData[0]&0xF;
        dstValue->ReserveBit1 = (pData[1]&0x78)>>3;
        dstValue->ReserveBit2 = (pData[5]&0x78)>>3;
        dstValue->ReserveBit3 = pData[9];
        dstValue->MutliTurnCnt = ((pData[1]&0x7)<<21) |((pData[2])<<14) |((pData[3])<<7) | ((pData[4]));
        dstValue->AbsPoseCnt = ((pData[5]&0x7)<<21) |((pData[6])<<14) |((pData[7])<<7) | ((pData[8]));
    }
    else{
        // valid error
        dstValue->ValidError = 1;
        return ERR_PROTOCOL_DATA;
    }
    return RES_OK;
}

uint8_t crc6(uint8_t *data, uint16_t length) {

    uint8_t  i;
    uint8_t  crc = 0;        // Initial value
    while(length--)
    {
        crc ^= *data++;        // crc ^= *data; data++;
        for ( i = 0; i < 8; i++ )
        {
            if ( crc & 0x80 )
                crc = (crc << 1) ^ 0x0C;
            else
                crc <<= 1;
        }
    }
    return crc>>2;
}

